Typical HAL CORDIC use cases for migration ¶
This section provides information about typical HAL CORDIC use cases for migration.
HAL CORDIC calculation use cases ¶
Note
The calculation sequence using the HAL CORDIC driver is similar between HAL1 and HAL2:
Initialization, configuration, and starting the calculation in four modes: polling, zero-overhead, interrupt, and DMA.
For DMA:
In HAL1, the user specifies how to handle the input and output data (using the HAL CORDIC driver) or delegates it to another HAL driver (for example, HAL ADC).
In HAL2, the user can either use:
The function
HAL_CORDIC_Calculate_DMA(). In this case, the input and output data are managed by the HAL CORDIC driver.The functions
HAL_CORDIC_Write_DMA()andHAL_CORDIC_Read_DMA()to individually control the CORDIC data streams for write and read directions. In this case, if the read or write should be managed by another peripheral (for example, ADC), the corresponding HAL CORDIC function (read/write) should be called.
For more details, see HAL CORDIC control functions migration.
Use case: HAL CORDIC calculate in polling / zero-overhead mode ¶
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
CORDIC_HandleTypeDef hcordic;
CORDIC_ConfigTypeDef cordic_config;
hcordic.Instance = CORDIC;
HAL_CORDIC_Init(&hcordic);
cordic_config.Function = CORDIC_FUNCTION_SINE;
cordic_config.Precision = CORDIC_PRECISION_6CYCLES;
cordic_config.Scale = CORDIC_SCALE_0;
cordic_config.NbWrite = CORDIC_NBWRITE_1;
cordic_config.NbRead = CORDIC_NBREAD_1;
cordic_config.InSize = CORDIC_INSIZE_32BITS;
cordic_config.OutSize = CORDIC_OUTSIZE_32BITS;
HAL_CORDIC_Configure(&hcordic, &cordic_config)
HAL_CORDIC_Calculate(&hcordic, input_data, output_data, 4, 10);
/* OR */
HAL_CORDIC_CalculateZO(&hcordic, input_data, output_data, 4, 10);
|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
hal_cordic_buffer_desc_t input_buffer = {
.p_data = input_data,
.size_word = INPUT_BUFFER_SIZE};
hal_cordic_buffer_desc_t output_buffer = {
.p_data = output_data,
.size_word = OUTPUT_BUFFER_SIZE};
hal_cordic_handle_t hcordic;
hal_cordic_config_t cordic_config;
HAL_CORDIC_Init(&hcordic, HAL_CORDIC);
HAL_RCC_CORDIC_EnableClock();
cordic_config.function = HAL_CORDIC_FUNCTION_SINE;
cordic_config.precision = HAL_CORDIC_PRECISION_6_CYCLE;
cordic_config.scaling_factor = HAL_CORDIC_SCALING_FACTOR_0;
cordic_config.nb_args = HAL_CORDIC_NB_ARG_1;
cordic_config.nb_results = HAL_CORDIC_NB_RESULT_1;
cordic_config.in_width = HAL_CORDIC_IN_WIDTH_32_BIT;
cordic_config.out_width = HAL_CORDIC_OUT_WIDTH_32_BIT;
HAL_CORDIC_SetConfig(&hcordic,&cordic_config);
HAL_CORDIC_Calculate(&hcordic, &input_buffer, &output_buffer, 10);
/* OR */
HAL_CORDIC_CalculateZeroOverhead(&hcordic, &input_buffer, &output_buffer, 10);
|
Key changes ¶
HAL2 uses buffer descriptors (
hal_cordic_buffer_desc_t) instead of raw pointers and element counts.HAL2 updates the API naming and signatures:
HAL_CORDIC_Configure()becomesHAL_CORDIC_SetConfig(), andHAL_CORDIC_CalculateZO()becomesHAL_CORDIC_CalculateZeroOverhead().HAL2 explicitly enables the peripheral clock using
HAL_RCC_CORDIC_EnableClock().
Use case: HAL CORDIC calculate in interrupt mode ¶
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
CORDIC_HandleTypeDef hcordic;
CORDIC_ConfigTypeDef cordic_config;
hcordic.Instance = CORDIC;
HAL_CORDIC_Init(&hcordic);
__HAL_RCC_CORDIC_CLK_ENABLE();
cordic_config.Function = CORDIC_FUNCTION_SINE;
cordic_config.Precision = CORDIC_PRECISION_6CYCLES;
cordic_config.Scale = CORDIC_SCALE_0;
cordic_config.NbWrite = CORDIC_NBWRITE_1;
cordic_config.NbRead = CORDIC_NBREAD_1;
cordic_config.InSize = CORDIC_INSIZE_32BITS;
cordic_config.OutSize = CORDIC_OUTSIZE_32BITS;
HAL_CORDIC_Configure(&hcordic, &cordic_config)
HAL_NVIC_SetPriority(CORDIC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CORDIC_IRQn);
HAL_CORDIC_Calculate_IT(&hcordic, input_data, output_data, 4);
/* Wait for the calculation complete callback:
HAL_CORDIC_CalculateCpltCallback() */
|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
hal_cordic_buffer_desc_t input_buffer = {
.p_data = input_data,
.size_word = INPUT_BUFFER_SIZE};
hal_cordic_buffer_desc_t output_buffer = {
.p_data = output_data,
.size_word = OUTPUT_BUFFER_SIZE};
hal_cordic_handle_t hcordic;
hal_cordic_config_t cordic_config;
HAL_CORDIC_Init(&hcordic, HAL_CORDIC);
HAL_RCC_CORDIC_EnableClock();
cordic_config.function = HAL_CORDIC_FUNCTION_SINE;
cordic_config.precision = HAL_CORDIC_PRECISION_6_CYCLE;
cordic_config.scaling_factor = HAL_CORDIC_SCALING_FACTOR_0;
cordic_config.nb_args = HAL_CORDIC_NB_ARG_1;
cordic_config.nb_results = HAL_CORDIC_NB_RESULT_1;
cordic_config.in_width = HAL_CORDIC_IN_WIDTH_32_BIT;
cordic_config.out_width = HAL_CORDIC_OUT_WIDTH_32_BIT;
HAL_CORDIC_SetConfig(&hcordic,&cordic_config);
HAL_CORTEX_NVIC_SetPriority(CORDIC_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(CORDIC_IRQn);
HAL_CORDIC_Calculate_IT(&hcordic, &input_buffer, &output_buffer);
/* Wait for the calculation complete callback:
HAL_CORDIC_CalculateCpltCallback() */
|
Key changes ¶
HAL2 uses buffer descriptors (
hal_cordic_buffer_desc_t) for inputs and outputs instead of raw pointers.HAL2 uses
HAL_CORTEX_NVIC_SetPriority()andHAL_CORTEX_NVIC_EnableIRQ()for NVIC configuration.HAL2 explicitly enables the peripheral clock using
HAL_RCC_CORDIC_EnableClock().
Related examples in HAL2 ¶
|
Example name |
Brief |
|---|---|
|
example_hal_cordic_sincos_it |
This example illustrates configuring the CORDIC unit via the HAL API to calculate sine and cosine of an array of angles using interrupt mode. |
Use case: HAL CORDIC calculate in DMA mode ¶
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
CORDIC_HandleTypeDef hcordic;
DMA_HandleTypeDef hGPDMA1_CH0;
DMA_HandleTypeDef hGPDMA1_CH1;
CORDIC_ConfigTypeDef cordic_config;
hcordic.Instance = CORDIC;
HAL_CORDIC_Init(&hcordic);
__HAL_RCC_CORDIC_CLK_ENABLE();
cordic_config.Function = CORDIC_FUNCTION_SINE;
cordic_config.Precision = CORDIC_PRECISION_6CYCLES;
cordic_config.Scale = CORDIC_SCALE_0;
cordic_config.NbWrite = CORDIC_NBWRITE_1;
cordic_config.NbRead = CORDIC_NBREAD_1;
cordic_config.InSize = CORDIC_INSIZE_32BITS;
cordic_config.OutSize = CORDIC_OUTSIZE_32BITS;
HAL_CORDIC_Configure(&hcordic, &cordic_config)
__HAL_RCC_GPDMA1_CLK_ENABLE();
hGPDMA1_CH0.Instance = GPDMA1_Channel0;
hGPDMA1_CH0.Init.Request = GPDMA1_REQUEST_CORDIC_WRITE;
hGPDMA1_CH0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
hGPDMA1_CH0.Init.Direction = DMA_MEMORY_TO_PERIPH;
hGPDMA1_CH0.Init.SrcInc = DMA_SINC_INCREMENTED;
hGPDMA1_CH0.Init.DestInc = DMA_DINC_FIXED;
hGPDMA1_CH0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
hGPDMA1_CH0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
hGPDMA1_CH0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
hGPDMA1_CH0.Init.SrcBurstLength = 1;
hGPDMA1_CH0.Init.DestBurstLength = 1;
hGPDMA1_CH0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
hGPDMA1_CH0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
hGPDMA1_CH0.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&hGPDMA1_CH0);
HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
__HAL_LINKDMA(hcordic, hdmaIn, hGPDMA1_CH0);
__HAL_RCC_GPDMA1_CLK_ENABLE();
hGPDMA1_CH1.Instance = GPDMA1_Channel1;
hGPDMA1_CH1.Init.Request = GPDMA1_REQUEST_CORDIC_READ;
hGPDMA1_CH1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
hGPDMA1_CH1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hGPDMA1_CH1.Init.SrcInc = DMA_SINC_FIXED;
hGPDMA1_CH1.Init.DestInc = DMA_DINC_INCREMENTED;
hGPDMA1_CH1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
hGPDMA1_CH1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
hGPDMA1_CH1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
hGPDMA1_CH1.Init.SrcBurstLength = 1;
hGPDMA1_CH1.Init.DestBurstLength = 1;
hGPDMA1_CH1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
hGPDMA1_CH1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
hGPDMA1_CH1.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&hGPDMA1_CH1);
HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
__HAL_LINKDMA(hcordic, hdmaOut, hGPDMA1_CH1);
HAL_CORDIC_Calculate_DMA(&hcordic, input_data, output_data, 4, CORDIC_DMA_DIR_IN_OUT);
/* Wait for the callbacks:
HAL_CORDIC_CalculateCpltCallback()
HAL_CORDIC_ErrorCallback() */
|
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U
int32_t input_data[INPUT_BUFFER_SIZE] = {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};
hal_cordic_buffer_desc_t input_buffer = {
.p_data = input_data,
.size_word = INPUT_BUFFER_SIZE};
hal_cordic_buffer_desc_t output_buffer = {
.p_data = output_data,
.size_word = OUTPUT_BUFFER_SIZE};
hal_cordic_handle_t hcordic;
hal_dma_handle_t hLPDMA1_CH0;
hal_dma_handle_t hLPDMA1_CH1;
hal_cordic_config_t cordic_config;
HAL_CORDIC_Init(&hcordic, HAL_CORDIC);
HAL_RCC_CORDIC_EnableClock();
cordic_config.function = HAL_CORDIC_FUNCTION_SINE;
cordic_config.precision = HAL_CORDIC_PRECISION_6_CYCLE;
cordic_config.scaling_factor = HAL_CORDIC_SCALING_FACTOR_0;
cordic_config.nb_args = HAL_CORDIC_NB_ARG_1;
cordic_config.nb_results = HAL_CORDIC_NB_RESULT_1;
cordic_config.in_width = HAL_CORDIC_IN_WIDTH_32_BIT;
cordic_config.out_width = HAL_CORDIC_OUT_WIDTH_32_BIT;
HAL_CORDIC_SetConfig(&hcordic,&cordic_config);
HAL_RCC_LPDMA1_EnableClock();
HAL_DMA_Init(&hLPDMA1_CH0, HAL_LPDMA1_CH0);
hal_dma_direct_xfer_config_t xfer_cfg_cordic_wr_dma;
xfer_cfg_cordic_wr_dma.request = HAL_LPDMA1_REQUEST_CORDIC_WR;
xfer_cfg_cordic_wr_dma.direction = HAL_DMA_DIRECTION_MEMORY_TO_PERIPH;
xfer_cfg_cordic_wr_dma.src_inc = HAL_DMA_SRC_ADDR_INCREMENTED;
xfer_cfg_cordic_wr_dma.dest_inc = HAL_DMA_DEST_ADDR_FIXED;
xfer_cfg_cordic_wr_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_cordic_wr_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_cordic_wr_dma.priority = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;
HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH0, &xfer_cfg_cordic_wr_dma);
HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH0_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH0_IRQn);
HAL_CORDIC_SetWriteDMA(&hCORDIC, &hLPDMA1_CH0);
HAL_RCC_LPDMA1_EnableClock();
HAL_DMA_Init(&hLPDMA1_CH1, HAL_LPDMA1_CH1);
hal_dma_direct_xfer_config_t xfer_cfg_cordic_rd_dma;
xfer_cfg_cordic_rd_dma.request = HAL_LPDMA1_REQUEST_CORDIC_RD;
xfer_cfg_cordic_rd_dma.direction = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_cordic_rd_dma.src_inc = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_cordic_rd_dma.dest_inc = HAL_DMA_DEST_ADDR_INCREMENTED;
xfer_cfg_cordic_rd_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.priority = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;
HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH1, &xfer_cfg_cordic_rd_dma);
HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH1_IRQn);
HAL_CORDIC_SetReadDMA(&hCORDIC, &hLPDMA1_CH1);
HAL_CORDIC_Calculate_DMA(&hcordic, &input_buffer, &output_buffer);
/* Wait for the callbacks:
HAL_CORDIC_CalculateCpltCallback()
HAL_CORDIC_WriteCpltCallback()
HAL_CORDIC_ErrorCallback() */
|
Key changes ¶
HAL2 configures CORDIC DMA channels explicitly using
HAL_CORDIC_SetWriteDMA()andHAL_CORDIC_SetReadDMA().HAL2 uses
hal_dma_direct_xfer_config_tandHAL_DMA_SetConfigPeriphDirectXfer()to configure DMA transfers.HAL2 introduces additional callbacks for split DMA streams (for example,
HAL_CORDIC_WriteCpltCallback()).
Related examples in HAL2 ¶
|
Example name |
Brief |
|---|---|
|
example_hal_cordic_sincos_dma |
This example illustrates configuring the CORDIC unit via the HAL API to calculate sine and cosine of an array of angles using DMA for efficient data transfer. |
- layout :
-
large_read_area
Use case: HAL CORDIC calculation in DMA mode with peripheral (ADC) ¶
In HAL1, to use the CORDIC peripheral together with another peripheral (such as ADC, Timer, etc.) in DMA mode, you can configure the DMA direction as follows:
CORDIC_DMA_DIR_IN
or
CORDIC_DMA_DIR_OUT
enables one-sided stream management by the CORDIC peripheral.
CORDIC_DMA_DIR_NONE
allows two peripherals to write to and read from CORDIC data registers.
In HAL2, the new functions
HAL_CORDIC_Write_DMA()
and
HAL_CORDIC_Read_DMA()
handle DMA write and read operations
separately for improved peripheral management.
In this use case, the ADC performs sampling, conversion, and writes the result directly to the
CORDIC
WDATA
register
using DMA.
The CORDIC peripheral then reads only the result. In HAL1, one-way stream management is implemented by setting the DMA
direction argument to
CORDIC_DMA_DIR_OUT. In HAL2, the read stream is managed using
HAL_CORDIC_Read_DMA()
instead.
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 32)
ADC_HandleTypeDef hadc4;
DMA_HandleTypeDef handle_GPDMA1_Channel10;
CORDIC_HandleTypeDef hcordic;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
static int32_t output_data[32];
uint32_t write_addr;
ADC_ChannelConfTypeDef sConfig = {0};
hadc4.Instance = ADC4;
hadc4.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc4.Init.Resolution = ADC_RESOLUTION_12B;
hadc4.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc4.Init.ScanConvMode = ADC4_SCAN_DISABLE;
hadc4.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc4.Init.LowPowerAutoPowerOff = ADC_LOW_POWER_NONE;
hadc4.Init.LowPowerAutoWait = DISABLE;
hadc4.Init.ContinuousConvMode = ENABLE;
hadc4.Init.NbrOfConversion = 1;
hadc4.Init.DiscontinuousConvMode = DISABLE;
hadc4.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc4.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc4.Init.DMAContinuousRequests = ENABLE;
hadc4.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_LOW;
hadc4.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc4.Init.SamplingTimeCommon1 = ADC4_SAMPLETIME_79CYCLES_5;
hadc4.Init.SamplingTimeCommon2 = ADC4_SAMPLETIME_79CYCLES_5;
hadc4.Init.OversamplingMode = DISABLE;
HAL_ADC_Init(&hadc4);
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC4_REGULAR_RANK_1;
sConfig.SamplingTime = ADC4_SAMPLINGTIME_COMMON_1;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hadc4, &sConfig);
__HAL_RCC_GPDMA1_CLK_ENABLE();
handle_GPDMA1_Channel10.Instance = GPDMA1_Channel10;
handle_GPDMA1_Channel10.Init.Request = GPDMA1_REQUEST_ADC4;
handle_GPDMA1_Channel10.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel10.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_GPDMA1_Channel10.Init.SrcInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel10.Init.DestInc = DMA_DINC_FIXED;
handle_GPDMA1_Channel10.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel10.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
handle_GPDMA1_Channel10.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel10.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel10.Init.DestBurstLength = 1;
handle_GPDMA1_Channel10.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
handle_GPDMA1_Channel10.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel10.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&handle_GPDMA1_Channel10);
HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
__HAL_LINKDMA(hadc, DMA_Handle, handle_GPDMA1_Channel10);
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
hcordic.Instance = CORDIC;
HAL_CORDIC_Init(&hcordic);
CORDIC_ConfigTypeDef cordic_config;
cordic_config.Function = CORDIC_FUNCTION_SINE;
cordic_config.Precision = CORDIC_PRECISION_6CYCLES;
cordic_config.Scale = CORDIC_SCALE_0;
cordic_config.NbWrite = CORDIC_NBWRITE_1;
cordic_config.NbRead = CORDIC_NBREAD_1;
cordic_config.InSize = CORDIC_INSIZE_32BITS;
cordic_config.OutSize = CORDIC_OUTSIZE_32BITS;
HAL_CORDIC_Configure(&hcordic, &cordic_config);
__HAL_RCC_GPDMA1_CLK_ENABLE()
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
handle_GPDMA1_Channel0.Init.Request = GPDMA1_REQUEST_CORDIC_READ;
handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel0.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_INCREMENTED;
handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
handle_GPDMA1_Channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&handle_GPDMA1_Channel0);
HAL_NVIC_SetPriority(GPDMA1_Channel10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel10_IRQn);
__HAL_LINKDMA(hcordic, hdmaOut, handle_GPDMA1_Channel0);
/* pInBuff is set to NULL as the input data stream to the CORDIC WDATA register will be handled by the ADC,
DMADirection is set to CORDIC_DMA_DIR_OUT as HAL_CORDIC will handle only the output data stream */
HAL_CORDIC_Calculate_DMA(&hcordic, NULL, output_data, (ADC_CONVERTED_DATA_BUFFER_SIZE), CORDIC_DMA_DIR_OUT);
write_addr = (uint32_t) &(CORDIC->WDATA);
/* pData = (uint32_t *)write_addr: ADC converted values written directly to the CORDIC WDATA register */
HAL_ADC_Start_DMA(&hadc4, (uint32_t *)write_addr, (ADC_CONVERTED_DATA_BUFFER_SIZE));
/* Wait for the callbacks:
HAL_ADC_ConvCpltCallback
HAL_ADC_ErrorCallback
HAL_CORDIC_CalculateCpltCallback
HAL_CORDIC_ErrorCallback*/
|
#define OUTPUT_BUFFER_SIZE ((uint32_t) 32)
ADC_TypeDef *instance = ADC1;
hal_adc_handle_t hADC1;
hal_dma_handle_t hGPDMA1_CH0;
hal_cordic_handle_t hCORDIC;
hal_dma_handle_t hGPDMA1_CH1;
hal_adc_config_t adc_config;
hal_adc_inj_config_t adc_inj_config;
static int32_t output_data[32];
static volatile uint32_t *write_addr;
hal_cordic_buffer_desc_t output_buffer = {
.p_data = output_data,
.size_word = OUTPUT_BUFFER_SIZE};
HAL_ADC_Init(&hADC1, HAL_ADC1);
hal_adc_config_t adc_config;
adc_config.clock = HAL_ADC_CLOCK_ASYNC_DIV4;
adc_config.resolution = HAL_ADC_RESOLUTION_14_BIT;
adc_config.trigger_freq_mode = HAL_ADC_TRIGGER_FREQ_HIGH;
adc_config.sampling_mode = HAL_ADC_SAMPLING_MODE_NORMAL;
adc_config.sampling_time_com1 = HAL_ADC_SAMPLING_TIME_814CYCLES_5;
adc_config.sampling_time_com2 = HAL_ADC_SAMPLING_TIME_814CYCLES_5;
HAL_ADC_SetConfig(&hADC1, &adc_config);
hal_adc_reg_config_t reg_config;
reg_config.trigger_src = HAL_ADC_REG_TRIG_SOFTWARE_START;
reg_config.trigger_edge = HAL_ADC_REG_TRIG_EDGE_NONE;
reg_config.sequencer_length = 1;
reg_config.sequencer_discont = HAL_ADC_REG_SEQ_DISCONT_DISABLE;
reg_config.continuous = HAL_ADC_REG_CONV_CONTINUOUS;
reg_config.overrun = HAL_ADC_REG_OVR_DATA_OVERWRITTEN;
reg_config.data_transfer = HAL_ADC_REG_DATA_TRANSFER_NONE;
reg_config.sequencer_mode = HAL_ADC_REG_SEQ_FIXED;
HAL_ADC_REG_SetConfig(&hADC1, ®_config);
hal_adc_channel_config_t adc_channel_config;
adc_channel_config.group = HAL_ADC_GROUP_REGULAR;
adc_channel_config.sequencer_rank = 1;
adc_channel_config.input_mode = HAL_ADC_IN_SINGLE_ENDED;
adc_channel_config.sampling_time = HAL_ADC_SAMPLING_TIME_814CYCLES;
HAL_ADC_SetConfigChannel(&hADC1, HAL_ADC_CHANNEL_4, &adc_channel_config);
hal_adc_inj_config_t adc_inj_config;
adc_inj_config.trigger_src = HAL_ADC_INJ_TRIG_SOFTWARE_START;
adc_inj_config.trigger_edge = HAL_ADC_INJ_TRIG_EDGE_NONE;
adc_inj_config.sequencer_length = 1;
adc_inj_config.sequencer_discont = HAL_ADC_INJ_SEQ_DISCONT_DISABLE;
HAL_ADC_INJ_SetConfig(&hADC1, &adc_inj_config);
adc_channel_config.group = HAL_ADC_GROUP_INJECTED;
HAL_ADC_SetConfigChannel(&hADC1, HAL_ADC_CHANNEL_4 , &adc_channel_config);
HAL_RCC_GPDMA1_EnableClock();
HAL_DMA_Init(&hGPDMA1_CH0, HAL_GPDMA1_CH0);
hal_dma_direct_xfer_config_t xfer_cfg_adc1_dma;
xfer_cfg_adc1_dma.request = HAL_GPDMA1_REQUEST_ADC1;
xfer_cfg_adc1_dma.direction = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_adc1_dma.src_inc = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_adc1_dma.dest_inc = HAL_DMA_DEST_ADDR_FIXED;
xfer_cfg_adc1_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_adc1_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_adc1_dma.priority = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;
HAL_DMA_SetConfigPeriphDirectXfer(&hGPDMA1_CH0, &xfer_cfg_adc1_dma);
HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH0_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH0_IRQn);
HAL_ADC_REG_SetDMA(&hADC1, &hGPDMA1_CH0);
HAL_RCC_GPIOC_EnableClock();
hal_gpio_config_t gpio_config;
gpio_config.mode = HAL_GPIO_MODE_ANALOG;
gpio_config.pull = HAL_GPIO_PULL_NO;
HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_3, &gpio_config);
hal_cordic_config_t cordic_config;
HAL_CORDIC_Init(&hCORDIC, HAL_CORDIC);
HAL_RCC_CORDIC_EnableClock();
cordic_config.function = LL_CORDIC_FUNCTION_MODULUS;
cordic_config.in_width = HAL_CORDIC_IN_WIDTH_32_BIT;
cordic_config.nb_arg = HAL_CORDIC_NB_ARG_1;
cordic_config.out_width = HAL_CORDIC_OUT_WIDTH_32_BIT;
cordic_config.nb_result = HAL_CORDIC_NB_RESULT_1;
cordic_config.scaling_factor = HAL_CORDIC_SCALING_FACTOR_0;
cordic_config.precision = HAL_CORDIC_PRECISION_5_CYCLE;
HAL_CORDIC_SetConfig(&hCORDIC,&cordic_config);
HAL_RCC_GPDMA1_EnableClock();
HAL_DMA_Init(&hGPDMA1_CH1, HAL_GPDMA1_CH1);
hal_dma_direct_xfer_config_t xfer_cfg_cordic_rd_dma;
xfer_cfg_cordic_rd_dma.request = HAL_GPDMA1_REQUEST_CORDIC_RD;
xfer_cfg_cordic_rd_dma.direction = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_cordic_rd_dma.src_inc = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_cordic_rd_dma.dest_inc = HAL_DMA_DEST_ADDR_INCREMENTED;
xfer_cfg_cordic_rd_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.priority = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;
HAL_DMA_SetConfigPeriphDirectXfer(&hGPDMA1_CH1, &xfer_cfg_cordic_rd_dma);
HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH1_IRQn);
HAL_CORDIC_SetReadDMA(&hCORDIC, &hGPDMA1_CH1);
/* Start reading the CORDIC output in DMA mode, while the input stream is handled by HAL_ADC */
HAL_CORDIC_Read_DMA(&hCORDIC, &output_buffer);
write_addr = HAL_CORDIC_GetWriteAddress(&hCORDIC);
HAL_ADC_Start(hADC);
/* p_data = (uint8_t const *)write_addr: ADC converted values written directly to the CORDIC WDATA register */
HAL_ADC_REG_StartConv_DMA(hADC, (uint8_t const *)write_addr, OUTPUT_BUFFER_SIZE*4);
/* Wait for the callbacks:
HAL_ADC_REG_DataTransferCpltCallback
HAL_ADC_ErrorCallback
HAL_CORDIC_CalculateCpltCallback()
HAL_CORDIC_ErrorCallback() */
|
Similarly to this use case, when using the CORDIC peripheral with a DAC in HAL1, the function
HAL_CORDIC_Calculate_DMA
is used with the
CORDIC_DMA_DIR_IN
argument. In HAL2, this is replaced by
HAL_CORDIC_Write_DMA().
Key changes ¶
HAL2 splits DMA stream management with dedicated APIs:
HAL_CORDIC_Write_DMA()andHAL_CORDIC_Read_DMA().HAL2 provides
HAL_CORDIC_GetWriteAddress()to let another peripheral (such as ADC) write directly to the CORDIC input register.HAL2 configures the CORDIC DMA streams explicitly using
HAL_CORDIC_SetReadDMA()(andHAL_CORDIC_SetWriteDMA()when needed).
Related examples in HAL2 ¶
No related example is listed in this document for this use case.







